<?php

namespace App\Console\Commands;

use App\Http\Models\Line;
use App\Http\Models\User;
use App\Http\Models\Order;
use App\Http\Models\Price;
use App\Http\Models\Record;
use Illuminate\Console\Command;
use App\Http\Models\ObjectModel;

class Fetch extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'fetch';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Command description';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        for ($i = 0; $i < 19; $i++) {
            $this->fetch();
            $this->compute();
            sleep(3);
        }
    }

    public function fetch()
    {
        $requestResults = file_get_contents('http://forex.wiapi.hexun.com/forex/sortlist?block=303&number=1000&title=15&commodityid=0&direction=0&start=0&column=code,name,type,price');
        // header("Content-type: text/html; charset=utf-8");
        $requestResults = trim($requestResults, '();');
        //比特币
        // $sendUrl = 'https://api.walian.cn/coins/chainIndex.open?en_name=BTC'; //短信接口的URL
        // $smsConf = '';
        // $content = $this->juhecurl($sendUrl,$smsConf,1);
        // $a = json_decode($content,true);
        //获取上一个值。如果一样就随机，如不一样就显示真实值
        $up = ObjectModel::where('body_tag_forex', 'USDCHF')->first();
        // $btc = $a['data']['coinIndex']['nowPrice'];
        $btc = (669080 + rand(100, 999));
        // if($btc == $up->body_price){
        //     $btc = (($up->body_price * 10000) + rand(10000,50000)) / 10000;
        // }
        $requestResults = json_decode($requestResults, TRUE);
        $objects = ObjectModel::where('id', '<', 18)->get();
        $requestResults = $requestResults['Data'][0];
        $arr = array();
        foreach ($requestResults as $k => $v) {
            // if ($v[0] == 'USDCHF') { //比特币
            //     $arr[$v[0]] = $btc * 10000;
            // } else {
            //     $arr[$v[0]] = $v[3];
            // }
            if($k == 0) {
                $btcObject['USDBTC'] = $btc * 100;
            }
            $arr[$v[0]] = $v[3];
        }
        $arr = array_merge($arr, $btcObject);
        $i = 0;
        foreach ($objects as $item) {
            $this->insertPrice($item, ($arr[$item->body_tag_forex] / 10000), date('Y-m-d H:i:s', time()), ($arr[$item->body_tag_forex] / 10000), ($arr[$item->body_tag_forex] / 1000), 0);
            $i++;
        }
        echo ('Fetch Done!');
    }

    public function juhecurl($url,$params=false,$ispost=0)
    {
        $httpInfo = array();
        $ch = curl_init();
        curl_setopt( $ch, CURLOPT_HTTP_VERSION , CURL_HTTP_VERSION_1_1 );
        curl_setopt( $ch, CURLOPT_USERAGENT , 'Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.172 Safari/537.22' );
        curl_setopt( $ch, CURLOPT_CONNECTTIMEOUT , 30 );
        curl_setopt( $ch, CURLOPT_TIMEOUT , 30);
        curl_setopt( $ch, CURLOPT_RETURNTRANSFER , true );
        if( $ispost )
        {
            curl_setopt( $ch , CURLOPT_POST , true );
            curl_setopt( $ch , CURLOPT_POSTFIELDS , $params );
            curl_setopt( $ch , CURLOPT_URL , $url );
        }
        else
        {
            if($params){
                curl_setopt( $ch , CURLOPT_URL , $url.'?'.$params );
            }else{
                curl_setopt( $ch , CURLOPT_URL , $url);
            }
        }
        $response = curl_exec( $ch );
        if ($response === FALSE) {
            //echo "cURL Error: " . curl_error($ch);
            return false;
        }
        $httpCode = curl_getinfo( $ch , CURLINFO_HTTP_CODE );
        $httpInfo = array_merge( $httpInfo , curl_getinfo( $ch ) );
        curl_close( $ch );
        return $response;
    }

    protected function insertPrice($object, $objectPrice, $objectPriceTime, $objectPriceMin, $objectPriceMax, $objectPriceInterval)
    {
        if (Price::where('id_object', $object->id)->where('body_price_time', date('Y-m-d H:i:s', time()))->count() == 0) {
            if (Price::where('id_object', $object->id)->where('body_price_time', $objectPriceTime)->count() == 0) {

                if (floatval($object->body_price) == floatval($objectPrice)) {
                    $object->body_price_repeat = intval($object->body_price_repeat) + 1;
                    if ($object->body_price_repeat >= 180) {
                        $object->body_status = 0;
                    }
                } else {

                    $object->body_price_repeat = 0;
                    $object->body_status = 1;

                    $price = new Price;
                    $price->id_object = $object->id;
                    $price->body_price = sprintf('%.' . $object->body_price_decimal . 'f', $objectPrice);
                    $price->body_price_time = $objectPriceTime;
                    $price->save();

                    $object->body_price_previous = $object->body_price;
                    $object->body_price = $price->body_price;
                    $object->body_price_min = $objectPriceMin;
                    $object->body_price_max = $objectPriceMax;
                    $object->body_price_interval = $objectPriceInterval;
                    $object->save();

                    Price::where('id_object', $object->id)->where('body_price_time', '<', date('Y-m-d H:i:s', strtotime($price->body_price_time) - 12800))->delete();
                }
            }
        } else {
            $price = Price::where('id_object', $object->id)->where('body_price_time', date('Y-m-d H:i:s', time()))->first();
            $object->body_price_previous = $object->body_price;
            $object->body_price = $price->body_price;
            $object->save();
        }
        $this->insertLine($object, $objectPrice, $objectPriceTime);
    }

    protected function insertLineItem($period, $object, $objectPrice, $objectPriceTime)
    {
        if (Line::where('id_object', $object->id)->where('body_period', $period)->where('created_at', '>=', date('Y-m-d H:i:s', time() - $period))->count() == 0) {
            $line = new Line;
            $line->id_object = $object->id;
            $line->body_period = $period;
            $line->body_open = sprintf('%.' . $object->body_price_decimal . 'f', $objectPrice);
            $line->body_high = $line->body_open;
            $line->body_low = $line->body_open;
            $line->body_close = $line->body_open;
            $line->body_volume = 0;
            $line->save();
            Line::where('id_object', $object->id)->where('body_period', $period)->where('created_at', '<', date('Y-m-d H:i:s', strtotime($objectPriceTime) - $period * 600))->delete();
        } else {
            $line = Line::where('id_object', $object->id)->where('body_period', $period)->where('created_at', '>=', date('Y-m-d H:i:s', time() - $period))->first();
            $line_closed_at = strtotime($line->created_at) + $line->body_period;
            if (time() < $line_closed_at) {

                $rel = array();
                if ($objectPrice > $line->body_high) {
                    $rel['body_high'] = sprintf('%.' . $object->body_price_decimal . 'f', $objectPrice);
                }
                if ($objectPrice < $line->body_low) {
                    $rel['body_low'] = sprintf('%.' . $object->body_price_decimal . 'f', $objectPrice);
                }
                $rel['body_close'] = sprintf('%.' . $object->body_price_decimal . 'f', $objectPrice);
                $rel['body_volume'] = $line->body_volume + mt_rand(0, 1);
                $rel['created_at'] = $line->created_at;
                $rel['updated_at'] = date('Y-m-d H:i:s', time());
                Line::whereId($line->id)->update($rel);
            }
        }
    }

    protected function insertLine($object, $objectPrice, $objectPriceTime)
    {
        if ($object->body_status == 1) {
            $this->insertLineItem(60, $object, $objectPrice, $objectPriceTime);
            $this->insertLineItem(300, $object, $objectPrice, $objectPriceTime);
            $this->insertLineItem(900, $object, $objectPrice, $objectPriceTime);
            $this->insertLineItem(1800, $object, $objectPrice, $objectPriceTime);
            $this->insertLineItem(3600, $object, $objectPrice, $objectPriceTime);
            $this->insertLineItem(86400, $object, $objectPrice, $objectPriceTime);
            $this->insertLineItem(604800, $object, $objectPrice, $objectPriceTime);
            $this->insertLineItem(2592000, $object, $objectPrice, $objectPriceTime);
        }

    }

    public function compute()
    {

        $orders = Order::where('striked_at', '0000-00-00 00:00:00')->get();
        foreach ($orders as $order) {

            $order_striked_time = strtotime($order->created_at) + $order->body_time;
            if ($order_striked_time <= time()) {

                if ($order->body_is_controlled == 0) {
                    $object_latestPrice = Price::where('id_object', $order->id_object)->where('body_price_time', '<=', date('Y-m-d H:i:s', $order_striked_time))->orderBy('created_at', 'desc')->first();
                    $order->body_price_striked = $object_latestPrice->body_price;
                }
                $order->striked_at = date('Y-m-d H:i:s', time());
                if (floatval($order->body_price_buying) == floatval($order->body_price_striked)) {
                    $order->body_is_win = 0;
                    $order->body_is_draw = 1;
                } else if (floatval($order->body_price_buying) < floatval($order->body_price_striked)) {
                    $order->body_is_win = $order->body_direction == 1 ? 1 : 0;
                    $order->body_is_draw = 0;
                } else {
                    $order->body_is_win = $order->body_direction == 0 ? 1 : 0;
                    $order->body_is_draw = 0;
                }
                $order->save();
                $user = User::where('id_wechat', $order->id_user)->first();
                if ($order->body_is_win == 1) {
                    $user->body_balance = $user->body_balance + $order->body_stake + $order->body_bonus;
                    $user->body_bonus = $user->body_bonus + $order->body_bonus;
                    $user->save();
                    $record = new Record;
                    $record->id_user = $user->id_wechat;
                    $record->id_order = $order->id;
                    $record->body_name = $order->body_direction == 1 ? '看涨盈利' : '看跌盈利';
                    $record->body_direction = 1;
                    $record->body_stake = $order->body_stake + $order->body_bonus;
                    $record->save();
                } else if ($order->body_is_draw == 1) {
                    $user->body_balance = $user->body_balance + $order->body_stake;
                    $user->save();
                    $record = new Record;
                    $record->id_user = $user->id_wechat;
                    $record->id_order = $order->id;
                    $record->body_name = $order->body_direction == 1 ? '看涨退回' : '看跌退回';
                    $record->body_direction = 1;
                    $record->body_stake = $order->body_stake;
                    $record->save();
                }
            }
        }

        echo('COMPUTE_DONE');


    }


    protected function computeNumber($number, $direction, $margin)
    {

        $numberExplode = explode('.', $number);
        $numberDecimal = end($numberExplode);
        $numberDecimalLength = strlen($numberDecimal);
        $numberDecimalControl = pow(0.1, $numberDecimalLength);

        if (env('ORDER_WILL_WIN')) {
            if ($direction == 1) {
                return floatval($number) + $margin * $numberDecimalControl;
            } else {
                return floatval($number) - $margin * $numberDecimalControl;
            }
        } else {
            if ($direction == 1) {
                return floatval($number) - $margin * $numberDecimalControl;
            } else {
                return floatval($number) + $margin * $numberDecimalControl;
            }
        }

    }

    protected function computeRate($id)
    {
        $orders_count = Order::where('id_user', $id)->count();
        if ($orders_count > 0) {
            $orders_is_win = Order::where('id_user', $id)->where('body_is_win', '1')->count();
            return ($orders_is_win / $orders_count) * 100;
        } else return 0;
    }

    protected function computePriceItem($time, $order, $object, $margin)
    {

        $price = Price::firstOrNew(array(
            'id_object' => $order->id_object,
            'body_price_time' => date('Y-m-d H:i:s', $time),
            'created_at' => date('Y-m-d H:i:s', $time)
        ));

        if ($order->body_stake > $price->body_rank) {
            $price->body_price = $this->computeNumber(sprintf('%.' . $object->body_price_decimal . 'f', $order->body_price_buying), $order->body_direction, $margin);
            $price->body_rank = $order->body_stake;
            $price->save();
        }
        return $price;

    }

    protected function computePrice($user, $order, $object)
    {

        $rate = $this->computeRate($user->id_wechat);

        if (floatval($order->body_stake) < 100) {
            $rate = 0;
        } else {
            if (floatval($order->body_stake) >= 200) $rate = $rate + 10;
            if (floatval($order->body_stake) >= 500) $rate = $rate + 10;
            if (floatval($order->body_stake) >= 1000) $rate = $rate + 15;
        }

        if (env('ORDER_WILL_LOST') ==1 || env('ORDER_WILL_WIN') == 1) {
            $rate = 101;
        }

        if (rand(1, 100) <= $rate) {

            $order_striked_time = strtotime($order->created_at) + $order->body_time;//到的时间

            $price = $this->computePriceItem($order_striked_time, $order, $object, mt_rand(1, 3));
//            $this->computePriceItem($order_striked_time - 9, $order, $object, 9);
//            $this->computePriceItem($order_striked_time - 8, $order, $object, 8);
//            $this->computePriceItem($order_striked_time - 7, $order, $object, 7);
//            $this->computePriceItem($order_striked_time - 6, $order, $object, 6);
//            $this->computePriceItem($order_striked_time - 5, $order, $object, 5);
//            $this->computePriceItem($order_striked_time - 4, $order, $object, 4);
//            $this->computePriceItem($order_striked_time - 3, $order, $object, 3);
//            $this->computePriceItem($order_striked_time - 2, $order, $object, 2);
//            $this->computePriceItem($order_striked_time - 1, $order, $object, 1);
//            $this->computePriceItem($order_striked_time + 1, $order, $object, 1);
//            $this->computePriceItem($order_striked_time + 2, $order, $object, -1);

            $order->body_price_striked = $price->body_price;
            $order->body_is_controlled = 1;
            $order->save();
        }

    }

    protected function computeNetwork($user, $order)
    {

        $introducerIndex = 0;   //推荐人等级
        while ($user->id_introducer != 0) {   //如果用户推荐人不为空
            $introducerIndex++;    //推荐人等级+1
            $introducer = User::where('id_wechat', $user->id_introducer)->first();  //从用户表查询有无此推荐人
            $introducer->body_transactions_network = $introducer->body_transactions_network + $order->body_stake; //推荐人的这个字段加上  此订单的金额

            if ($introducerIndex <= 3) {  //如果推荐人等级在三级以内

                $bonus = floatval($order->body_stake * floatval(env("AGENT_$introducerIndex"))); //定义奖金   等于订单金额*当前代理等级的金额。
                if ($bonus < 0.01) $bonus = 0.01;  //如果奖金小于0.01就默认为0.01

                $introducer->body_balance = floatval($introducer->body_balance) + $bonus;  //介绍人的余额加上奖金

                $record = new Record;   //新建存储记录
                $record->id_user = $introducer->id_wechat;  //用户为介绍人
                $record->id_refer = $user->id_wechat;  //
                $record->body_name = '推广收入';
                $record->body_direction = 1;
                $record->body_stake = $bonus;
                $record->save();

            }

            $introducer->save();
            return $introducer;
        }

    }
}
